#!/usr/bin/python
# -*- coding: utf-8 -*-

import requests
from concurrent.futures import ThreadPoolExecutor

class HttpConnectionPool():

    DEFAULT_HEADER_DICT = {"Content-Type": "application/json"}

    def get(self, **kwargs):
        r"""
        :param kwargs:
        :return: response json data
        """
        return self.request.get(url=self.request_url, **kwargs).json()

    def post(self, data=None, json=None, **kwargs):
        r"""
        :param url: URL for the new :class:`Request` object.
        :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`.
        :param json: (optional) json to send in the body of the :class:`Request`.
        :return: response json data
        """
        return self.request.post(url=self.request_url, data=data, json=json, **kwargs).json()

    def pack(self, data, level):
        json_data = {
            "requestId": '',
            "callModelCode": "TableTrolley",
            "invokedModelCode": "",
            "invokedModelMethod": "",
            "callStep": 0,
            "srcIp": "",
            "logLevel": str(level),
            "message": str(data)
        }
        return json_data

    def async_post(self, data=None, json=None, callback=None, **kwargs):
        r"""
        :param data:
        :param json:
        :param callback:
        :param kwargs:
        :return:
        """
        if self.is_multi_thread:
            self.thread_executor.submit(self.async_post_handler, json=json, callback=callback)
        else:
            raise Exception("Not MultiThread Mode")

    def async_post_handler(self, data=None, json=None, callback=None, **kwargs):
        r"""
        :param data: (optional) Dictionary, bytes, or file-like object to send in the body
        :param json: (optional) json to send in the body
        :param callback: callback function to handle the request response
        :param kwargs: others
        :return: None
        """
        response = self.request.post(url=self.request_url, data=data, json=json, **kwargs).json()
        if callback is not None:
            callback(response)


    def __init__(self, request_url, multi_thread=False, pool_maxsize=10, multi_thread_workers=3):
        r"""
        :param request_url: service url
        :param multi_thread: True for opening multi_thread mode, False for closing
        :param pool_maxsize: http pool size, default num: 10
        :param multi_thread_workers: thread pool size, default num: 2
        """
        self.request_url = request_url
        self.request = requests.Session()
        self.is_multi_thread = multi_thread
        if self.is_multi_thread:
            self.thread_executor = ThreadPoolExecutor(max_workers=multi_thread_workers)
        requests_adapter = requests.adapters.HTTPAdapter(max_retries=3, pool_maxsize=pool_maxsize)
        self.request.mount(request_url, requests_adapter)



"""
# 例子
同步请求：
ip = "http://10.203.247.203:8888/services/log/logging"
api_gw = "http://public-int-gw.intsit.sfdc.com.cn:1080/services/log/logging"
json_data = {
    "requestId": '',
    "callModelCode": "pythonTest",
    "invokedModelCode": "",
    "invokedModelMethod": "",
    "callStep": 0,
    "srcIp": "",
    "logLevel": "INFO",
    "message": "testing..."
}

http_connection_pool = HttpConnectionPool(ip)
res = http_connection_pool.post(json=json_data)
print(res)

异步请求:
http_connection_pool = HttpConnectionPool(ip, multi_thread=True)
http_connection_pool.async_post(json=json_data)
# 如果需要对异步response做处理，自定义callback函数
def handler(json_response):
    # do something
    print(json_response)
http_connection_pool.async_post(json=json_data, callback=handler)
"""






